import OptionParamsModel from "../model/OptionParams.model";
import { Config } from "../config/index.config";
import { Injectable } from "../annotation/Ioc.annotation";
import * as Hls from "hls.js";
import {VideoMimeType} from "../config/VideoMimeType.config";
import {Dom} from "../annotation/Dom.annotation";
@Injectable()
export class Utils {

    @Dom()
    private readonly Video!: HTMLVideoElement;

    public $(el: string): any {
        return document.querySelector(el)
    }

    /**
     * 自动调用类中的事件绑定方法
     * @param params 类数组
     */
    public callMethods(params:  {new (...args: any[]): {}; }[] ): void {
        setTimeout(() =>
            params.forEach((val: { new (): any; } ) =>
            Object.getOwnPropertyNames(val.prototype).splice(1).filter(f =>
                f.includes("BindEvent")).forEach(v =>
                (new val())[v]())),400)
    }

    /**
     * 修改元素类名
     * @param dom
     * @param className
     */
    addClassName<E extends HTMLElement>(dom: E, className: string): void {
        dom.classList.toggle(className)
    }



    /**
     * 视同用户填入的模板，传入配置，渲染输出HTML
     */
    public getLayout(): string {
        let render = require(`../../assets/tpl/${OptionParamsModel.OptionParams.layout}.pug`)
        return render({ params: Object.assign(OptionParamsModel.OptionParams, Config.IconConfig) })
    }

    /**
     * 将 string 转换为 dom 元素
     * @param arg
     * @constructor
     */
    public ParseDom (arg: string): HTMLElement {
        var objE = document.createElement("div");
        objE.innerHTML = arg;
        return objE.childNodes[0] as HTMLElement;
    }

    public Render() {

        // // 获取dom树中最后一个child也就是 script
        // let oldScript = father.lastChild;
        // // 从dom树中删除 script 代码，因为不管是innerHTML还是appendChild dom中的script都不执行
        // // 所以需要特殊处理
        // father.removeChild(father.childNodes[father.childNodes.length-1])
        // // 将去除 script 后的dom树插入到网页中
        // el.appendChild(father);
        //
        // // 生成 script，写入 js，插入 到网页中，这时候js可以执行！
        // let newScript = document.createElement('script');
        // newScript.type = 'text/javascript';
        // newScript.innerHTML = (oldScript as HTMLElement).innerHTML;
        // el.appendChild(newScript);
    }

    /**
     * 使用fetch 获取视频地址的编码类型，
     * 然后采用不同的播放方式
     * @constructor
     */
    public async CheckVideoType(URL: string): Promise<void> {
        let ContentType = (await fetch(URL, { headers: { range: "bytes=0-50" } })).headers.get("Content-Type");

        switch (ContentType) {
            // HLS 播放支持
            case VideoMimeType.HLS:
                this.PlayHls(this.Video, URL)
                break;
            // MP4播放支持
            case VideoMimeType.MP4:
                this.Video.src = URL;
                break;
            // MP4不同编码的播放支持
            case VideoMimeType.STREA:
                this.Video.src = URL;
                break;
            default:
                throw new Error("不支持播放的视频地址")
        }
    }

    /**
     * 下载文件
     * @param href 文件地址
     * @param fileType 文件类型
     */
    downLoadFile(href: string, fileType = 'image/png') {
        var dlLink = document.createElement('a');
        dlLink.download = `AVideo_${(new Date()).valueOf().toString()}`;
        dlLink.href = href;
        dlLink.dataset.downloadurl = [fileType, dlLink.download, dlLink.href].join(':');

        document.body.appendChild(dlLink);
        dlLink.click();
        document.body.removeChild(dlLink);
    }

    /**
     * 格式化时间
     * @param t
     */
    formatTime(t: number){
        var h: string | number = parseInt(String(t / 3600))
        h = h<10?'0'+h:h
        var m: string | number = parseInt(String(t % 3600 / 60))
        m = m<10?'0'+m:m
        var s: string | number = parseInt(String(t % 60))
        s = s<10?'0'+s:s
        return h+':'+m+':'+s
    }

    /**
     * 使用插件 hls.js 播放视频
     * @param Video
     * @param url
     * @constructor
     */
    public PlayHls(Video: HTMLVideoElement, url: string) {
        let hls = new Hls();
        hls.loadSource(url);
        hls.attachMedia(Video);
    }

}
